/**
 *
 * @file
 * @author Filipe Mutz
 *
 * @section DESCRIPTION
 *
 * This file contains the implementation of the methods of the weightless vg-ram neuron class
 */

#include "neuron_vgram.h"

/**
 * TODO: Conferir se o codigo abaixo esta correto!! Tenho quase certeza que ja tenho um codigo novo melhor
 */

namespace nn_lib
{
	namespace neuron
	{
		template<class OutputClass>
		NeuronVGRAM<OutputClass>::NeuronVGRAM()
		{
		}


		template<class OutputClass>
		NeuronVGRAM<OutputClass>::~NeuronVGRAM()
		{
		}


		template<class OutputClass> void
		NeuronVGRAM<OutputClass>::train(vector<int> input_vector, OutputClass expected_output)
		{
			pair<vector<float>, OutputClass> neuron_memory_item;

			neuron_memory_item.first = input_vector;
			neuron_memory_item.second = expected_output;

			neuron_memory.push_back(neuron_memory_item);
		}


		template<class OutputClass> OutputClass
		NeuronVGRAM<OutputClass>::test(vector<int> input_vector)
		{
			int i, is_first = 1, min_hamming_dist_position = 0;
			double hamming_dist = 0, min_hamming_dist = 0;

			if (neuron_memory.size() == 0)
				exit(printf("Error: Trying to test an empty neuron\n"));

			for (i = 0; i < (int) neuron_memory.size(); i++)
			{
				hamming_dist = calculate_hamming_distance(input_vector, neuron_memory[i].first);

				if (is_first)
				{
					min_hamming_dist = hamming_dist;
					is_first = 0;
				}
				else
				{
					// TODO: save vectors with equals hamming dist to choose randomly between them
					if (hamming_dist < min_hamming_dist)
					{
						min_hamming_dist = hamming_dist;
						min_hamming_dist_position = i;
					}
				}
			}

			return neuron_memory[min_hamming_dist_position].second;
		}
	}
}
